﻿
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using UniRlv.Server.ILayer;

namespace UniRlv.Server
{
    class ServerOprImp : MarshalByRefObject, IServerOpr
    {
        /// <summary>
        /// 测试服务器连接是否正常
        /// </summary>
        /// <returns></returns>
        public bool TestConnect(ref string errMsg)
        {
            try
            {
                string write = "select count(id) as num from [User]";
                object scalar = SqlHelper.ExecuteScalar(write, ref errMsg);
                if (scalar != null)
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                errMsg = ex.Message;
                return false;
            }
        }

        /// <summary>
        /// 返回首行首列
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public object GetScalar(string sql, int key, ref string errDesc)
        {
            if (key == 112233)
            {
                return SqlHelper.ExecuteScalar(sql, ref errDesc);
            }

            return null;
        }

        /// <summary>
        /// 增加、删除、修改记录
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public bool ExecuteNonQuery(string sql, int key, ref string errDesc)
        {
            if (key == 112233)
            {
                return SqlHelper.ExecuteNonQuery(sql, ref errDesc) > 0;
            }

            return false;
        }

        /// <summary>
        /// 同时增加、删除、修改多条记录
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="key"></param>
        /// <param name="errDesc"></param>
        /// <returns></returns>
        public bool ExecuteNonQueryTran(string sql, int key, ref string errDesc)
        {
            string[] sqls = sql.Split(new char[]
			{
				'|'
			});

            errDesc = sql;

            if (key == 112233)
            {
                return SqlHelper.ExecuteSqlTran(sqls, ref errDesc);
            }

            return false;
        }

        /// <summary>
        /// 查询记录
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public string Query(string sql, int key)
        {
            List<Dictionary<string, object>> li = new List<Dictionary<string, object>>();
            Dictionary<string, object> res = new Dictionary<string, object>();
            bool bRes = false; ;
            string errDesc = string.Empty;

            if (key == 112233)
            {
                DataTable dt = SqlHelper.ExecuteTable(sql, ref errDesc);

                if (dt != null)
                {
                    Dictionary<string, object> dic;
                    foreach (DataRow dr in dt.Rows)
                    {
                        dic = new Dictionary<string, object>();
                        for (int i = 0; i < dt.Columns.Count; i++)
                        {
                            dic.Add(dt.Columns[i].ColumnName, dr[i].ToString());
                        }

                        li.Add(dic);
                    }
                    bRes = true;
                }

            }
            else
            {
                errDesc = "key值错误";
            }


            res.Add("msg", errDesc);
            res.Add("res", bRes);
            res.Add("obj", JsonHelper.ToJson<List<Dictionary<string, object>>>(li));

            return JsonHelper.ToJson<Dictionary<string, object>>(res);
        }

        /// <summary>
        /// 查询单记录
        /// </summary>
        /// <param name="sql"></param>
        /// <param name="key"></param>
        /// <returns></returns>
        public string QuerySingle(string sql, int key)
        {
            Dictionary<string, object> res = new Dictionary<string, object>();
            Dictionary<string, object> obj = new Dictionary<string, object>();
            bool bRes = false;
            string errDesc = string.Empty;

            if (key == 112233)
            {
                DataTable dt = SqlHelper.ExecuteTable(sql, ref errDesc);

                if (dt != null && dt.Rows.Count > 0)
                {
                    for (int i = 0; i < dt.Columns.Count; i++)
                    {
                        obj.Add(dt.Columns[i].ColumnName, dt.Rows[0][i].ToString());
                    }

                    bRes = true;
                }
                else
                {
                    errDesc = "无法查到记录";
                }

            }
            else
            {
                errDesc = "key值错误";
            }


            res.Add("msg", errDesc);
            res.Add("res", bRes);
            res.Add("obj", JsonHelper.ToJson<Dictionary<string, object>>(obj));

            return JsonHelper.ToJson<Dictionary<string, object>>(res);
        }

        //重载生命周期函数，使之无限长

        public override object InitializeLifetimeService()
        {
            //return base.InitializeLifetimeService();
            return null;
        }

        public Dictionary<string, string> IfNeedUpdate(Dictionary<string, string> files, ref string errDesc)
        {
            string dir = ConfigurationHelper.AppGetString("updateDir");
            IEnumerable<string> localFiles = Directory.EnumerateFiles(Path.Combine(Application.StartupPath, dir), "*.dll", SearchOption.TopDirectoryOnly).Union(Directory.EnumerateFiles(dir, "*.exe", SearchOption.TopDirectoryOnly));

            Dictionary<string, string> dict = new Dictionary<string, string>();
            FileVersionInfo fv;
            int ver;
            string fileName;

            foreach (string item in localFiles)
            {
                fileName = Path.GetFileName(item);
                if (files.ContainsKey(fileName))
                {
                    fv = System.Diagnostics.FileVersionInfo.GetVersionInfo(item);
                    if (CompareVersion(fv, files[fileName]))
                    {
                        dict.Add(fileName, fv.ProductVersion);
                    } 
                }
                
            }

            return dict;
        }

        public byte[] DownloadFile(string fileName, ref string errDesc)
        {
            string dir = ConfigurationHelper.AppGetString("updateDir");
            string filePath = Path.Combine(Application.StartupPath, dir);
            filePath = Path.Combine(filePath, fileName);

            if (File.Exists(filePath))
            {
                byte[] bs = File.ReadAllBytes(filePath);
                return CompressBytes(bs);
            }
            else
            {
                errDesc = "文件不存在";
                return null;
            }
        }

        //压缩字节
        //1.创建压缩的数据流 
        //2.设定compressStream为存放被压缩的文件流,并设定为压缩模式
        //3.将需要压缩的字节写到被压缩的文件流
        private byte[] CompressBytes(byte[] bytes)
        {
            using (MemoryStream compressStream = new MemoryStream())
            {
                using (var zipStream = new GZipStream(compressStream, CompressionMode.Compress))
                    zipStream.Write(bytes, 0, bytes.Length);
                return compressStream.ToArray();
            }
        }

        /// <summary>
        /// 比较版本号
        /// </summary>
        /// <param name="fv">本地版本号</param>
        /// <param name="version">客户端版本号: x.x.x.x </param>
        /// <returns> true：fv更新  false：version更新 </returns>
        private bool CompareVersion(FileVersionInfo fv, string version)
        {
            string[] items = version.Split(new char[] { '.' }, StringSplitOptions.RemoveEmptyEntries);
            int majorVer = 0, minorVer = 0, thirdVer = 0, fourVer = 0;

            try
            {
                majorVer = Convert.ToInt32(items[0]);

                if (majorVer<fv.FileMajorPart)
                {
                    return true;
                }
                else if (majorVer > fv.FileMajorPart)
                {
                    return false;
                }

                if (items.Length>1)
                {
                    minorVer = Convert.ToInt32(items[1]);

                    if (minorVer < fv.FileMinorPart)
                    {
                        return true;
                    }
                    else if (minorVer > fv.FileMinorPart)
                    {
                        return false;
                    }
                }

                if (items.Length > 2)
                {
                    thirdVer = Convert.ToInt32(items[2]);

                    if (thirdVer < fv.FileBuildPart)
                    {
                        return true;
                    }
                    else if (thirdVer > fv.FileBuildPart)
                    {
                        return false;
                    }
                }

                if (items.Length > 3)
                {
                    fourVer = Convert.ToInt32(items[3]);

                    if (fourVer < fv.FilePrivatePart)
                    {
                        return true;
                    }
                    else if (fourVer > fv.FilePrivatePart)
                    {
                        return false;
                    }
                }

                return false;//完全一样
            }
            catch (Exception exp)
            {
                Console.WriteLine("获取版本号异常：" + exp.Message);
                return true;
            }
        }

        public bool IfTableExist(string tbName)
        {
            string sql = string.Format("select COUNT(*) from dbo.sysobjects where id = object_id(N'{0}') and OBJECTPROPERTY(id, N'IsUserTable') = 1", tbName);
            string msg = string.Empty;

            object obj = SqlHelper.ExecuteScalar(sql, ref msg);

            if (string.IsNullOrEmpty(msg))
            {
                return obj != null && Convert.ToInt32(obj) > 0;
            }

            return false;
        }

        public bool IfColumnExist(string tbName, string col)
        {
            string sql = string.Format("select COL_LENGTH( '{0}','{1}')", tbName, col);
            string msg = string.Empty;

            object obj = SqlHelper.ExecuteScalar(sql, ref msg);

            if (string.IsNullOrEmpty(msg))
            {
                return obj != null && obj != DBNull.Value && Convert.ToInt32(obj) > 0;
            }

            return false;
        }



        public bool AddColumn(string tbName, string col, int key, string desc, ref string errDesc)
        {
            string sql = string.Format("alter table {0} add {1} {2}", tbName, col, desc);
            if (key == 112233)
            {
                SqlHelper.ExecuteNonQuery(sql, ref errDesc);
                return true;
            }
            else
            {
                errDesc = "key值错误";
            }

            return false;
        }


        public bool ExcuteBulkCopy(string tbDest, DataTable dtSrc, ref string errDesc)
        {
            SqlBulkCopyColumnMapping map;
            List<SqlBulkCopyColumnMapping> maps = new List<SqlBulkCopyColumnMapping>();
            
            foreach (DataColumn item in dtSrc.Columns)
	        {
                if (item.ColumnName.Equals("ID"))
                {
                    map = new SqlBulkCopyColumnMapping("id", "id");
                }
                else
                {
                    map = new SqlBulkCopyColumnMapping(item.ColumnName, item.ColumnName);
                }
		        
                maps.Add(map);
	        }

            try
            {
                SqlHelper.ExcuteBulkCopy(tbDest, dtSrc, maps.ToArray());
                return true;
            }
            catch (Exception exp)
            {
                errDesc = exp.Message;
                return false;
            }
            
        }

        public bool BackupTask(List<string> ids, ref string errDesc)
        {
            bool bRes = true;

            foreach (var item in ids)
            {
                bRes &= BkTask(Convert.ToInt32(item), ref errDesc);

                if (!bRes)
                {
                    return false;
                }
            }

            return true;
        }

        private bool BkTask(int id, ref string msg)
        {
            msg = string.Empty;

            SqlParameter[] sp = new SqlParameter[4];

            sp[0] = new SqlParameter("@InStrPara", SqlDbType.VarChar, 1024);

            sp[1] = new SqlParameter("@wp", SqlDbType.Int);
            sp[1].Value = id;

            sp[2] = new SqlParameter("@lp", SqlDbType.Int);

            sp[3] = new SqlParameter("@Res", SqlDbType.Int);
            sp[3].Direction = ParameterDirection.Output;

            SqlHelper.ExecuteNonQueryProc("uni_backup_code_by_task", ref msg, sp);

            Console.WriteLine(DateTime.Now.ToString("[HH:mm:ss.fff]") + "开始备份任务，id=" + id);
            if (!string.IsNullOrEmpty(msg))
            {
                Console.WriteLine("备份任务错误：" + msg);

                return false;
            }
            Console.WriteLine(DateTime.Now.ToString("[HH:mm:ss.fff]") + "结束备份任务");

            return true;
        }
    }
}
